{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "43fb16cb",
   "metadata": {},
   "source": [
    "# Serialization\n",
    "\n",
    "It is often preferrable to store prompts not as python code but as files. This can make it easy to share, store, and version prompts. This notebook covers how to do that in LangChain, walking through all the different types of prompts and the different serialization options.\n",
    "\n",
    "At a high level, the following design principles are applied to serialization:\n",
    "\n",
    "1. Both JSON and YAML are supported. We want to support serialization methods that are human readable on disk, and YAML and JSON are two of the most popular methods for that. Note that this rule applies to prompts. For other assets, like examples, different serialization methods may be supported.\n",
    "\n",
    "2. We support specifying everything in one file, or storing different components (templates, examples, etc) in different files and referencing them. For some cases, storing everything in file makes the most sense, but for others it is preferrable to split up some of the assets (long templates, large examples, reusable components). LangChain supports both.\n",
    "\n",
    "There is also a single entry point to load prompts from disk, making it easy to load any type of prompt."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2c8d7587",
   "metadata": {},
   "outputs": [],
   "source": [
    "# All prompts are loaded through the `load_prompt` function.\n",
    "from langchain.prompts import load_prompt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cddb465e",
   "metadata": {},
   "source": [
    "## PromptTemplate\n",
    "\n",
    "This section covers examples for loading a PromptTemplate."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4d4b40f2",
   "metadata": {},
   "source": [
    "### Loading from YAML\n",
    "This shows an example of loading a PromptTemplate from YAML."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2d6e5117",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_type: prompt\r\n",
      "input_variables:\r\n",
      "    [\"adjective\", \"content\"]\r\n",
      "template: \r\n",
      "    Tell me a {adjective} joke about {content}.\r\n"
     ]
    }
   ],
   "source": [
    "!cat simple_prompt.yaml"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "4f4ca686",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tell me a funny joke about chickens.\n"
     ]
    }
   ],
   "source": [
    "prompt = load_prompt(\"simple_prompt.yaml\")\n",
    "print(prompt.format(adjective=\"funny\", content=\"chickens\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "362eadb2",
   "metadata": {},
   "source": [
    "### Loading from JSON\n",
    "This shows an example of loading a PromptTemplate from JSON."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "510def23",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\r\n",
      "    \"_type\": \"prompt\",\r\n",
      "    \"input_variables\": [\"adjective\", \"content\"],\r\n",
      "    \"template\": \"Tell me a {adjective} joke about {content}.\"\r\n",
      "}\r\n"
     ]
    }
   ],
   "source": [
    "!cat simple_prompt.json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "de75e959",
   "metadata": {},
   "outputs": [],
   "source": [
    "prompt = load_prompt(\"simple_prompt.json\")\n",
    "print(prompt.format(adjective=\"funny\", content=\"chickens\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1d788f9",
   "metadata": {},
   "source": [
    "Tell me a funny joke about chickens."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d788a83c",
   "metadata": {},
   "source": [
    "### Loading template from a file\n",
    "This shows an example of storing the template in a separate file and then referencing it in the config. Notice that the key changes from `template` to `template_path`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5547760d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tell me a {adjective} joke about {content}."
     ]
    }
   ],
   "source": [
    "!cat simple_template.txt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9cb13ac5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\r\n",
      "    \"_type\": \"prompt\",\r\n",
      "    \"input_variables\": [\"adjective\", \"content\"],\r\n",
      "    \"template_path\": \"simple_template.txt\"\r\n",
      "}\r\n"
     ]
    }
   ],
   "source": [
    "!cat simple_prompt_with_template_file.json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "762cb4bf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tell me a funny joke about chickens.\n"
     ]
    }
   ],
   "source": [
    "prompt = load_prompt(\"simple_prompt_with_template_file.json\")\n",
    "print(prompt.format(adjective=\"funny\", content=\"chickens\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ae191cc",
   "metadata": {},
   "source": [
    "## FewShotPromptTemplate\n",
    "\n",
    "This section covers examples for loading few-shot prompt templates."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9828f94c",
   "metadata": {},
   "source": [
    "### Examples\n",
    "This shows an example of what examples stored as json might look like."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "b21f5b95",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\r\n",
      "    {\"input\": \"happy\", \"output\": \"sad\"},\r\n",
      "    {\"input\": \"tall\", \"output\": \"short\"}\r\n",
      "]\r\n"
     ]
    }
   ],
   "source": [
    "!cat examples.json"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3052850",
   "metadata": {},
   "source": [
    "And here is what the same examples stored as yaml might look like."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "901385d1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "- input: happy\r\n",
      "  output: sad\r\n",
      "- input: tall\r\n",
      "  output: short\r\n"
     ]
    }
   ],
   "source": [
    "!cat examples.yaml"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e300335",
   "metadata": {},
   "source": [
    "### Loading from YAML\n",
    "This shows an example of loading a few-shot example from YAML."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "e2bec0fc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_type: few_shot\r\n",
      "input_variables:\r\n",
      "    [\"adjective\"]\r\n",
      "prefix: \r\n",
      "    Write antonyms for the following words.\r\n",
      "example_prompt:\r\n",
      "    _type: prompt\r\n",
      "    input_variables:\r\n",
      "        [\"input\", \"output\"]\r\n",
      "    template:\r\n",
      "        \"Input: {input}\\nOutput: {output}\"\r\n",
      "examples:\r\n",
      "    examples.json\r\n",
      "suffix:\r\n",
      "    \"Input: {adjective}\\nOutput:\"\r\n"
     ]
    }
   ],
   "source": [
    "!cat few_shot_prompt.yaml"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "98c8f356",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Write antonyms for the following words.\n",
      "\n",
      "Input: happy\n",
      "Output: sad\n",
      "\n",
      "Input: tall\n",
      "Output: short\n",
      "\n",
      "Input: funny\n",
      "Output:\n"
     ]
    }
   ],
   "source": [
    "prompt = load_prompt(\"few_shot_prompt.yaml\")\n",
    "print(prompt.format(adjective=\"funny\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13620324",
   "metadata": {},
   "source": [
    "The same would work if you loaded examples from the yaml file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "831e5e4a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_type: few_shot\r\n",
      "input_variables:\r\n",
      "    [\"adjective\"]\r\n",
      "prefix: \r\n",
      "    Write antonyms for the following words.\r\n",
      "example_prompt:\r\n",
      "    _type: prompt\r\n",
      "    input_variables:\r\n",
      "        [\"input\", \"output\"]\r\n",
      "    template:\r\n",
      "        \"Input: {input}\\nOutput: {output}\"\r\n",
      "examples:\r\n",
      "    examples.yaml\r\n",
      "suffix:\r\n",
      "    \"Input: {adjective}\\nOutput:\"\r\n"
     ]
    }
   ],
   "source": [
    "!cat few_shot_prompt_yaml_examples.yaml"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "6f0a7eaa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Write antonyms for the following words.\n",
      "\n",
      "Input: happy\n",
      "Output: sad\n",
      "\n",
      "Input: tall\n",
      "Output: short\n",
      "\n",
      "Input: funny\n",
      "Output:\n"
     ]
    }
   ],
   "source": [
    "prompt = load_prompt(\"few_shot_prompt_yaml_examples.yaml\")\n",
    "print(prompt.format(adjective=\"funny\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4870aa9d",
   "metadata": {},
   "source": [
    "### Loading from JSON\n",
    "This shows an example of loading a few-shot example from JSON."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "9d996a86",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\r\n",
      "    \"_type\": \"few_shot\",\r\n",
      "    \"input_variables\": [\"adjective\"],\r\n",
      "    \"prefix\": \"Write antonyms for the following words.\",\r\n",
      "    \"example_prompt\": {\r\n",
      "        \"_type\": \"prompt\",\r\n",
      "        \"input_variables\": [\"input\", \"output\"],\r\n",
      "        \"template\": \"Input: {input}\\nOutput: {output}\"\r\n",
      "    },\r\n",
      "    \"examples\": \"examples.json\",\r\n",
      "    \"suffix\": \"Input: {adjective}\\nOutput:\"\r\n",
      "}   \r\n"
     ]
    }
   ],
   "source": [
    "!cat few_shot_prompt.json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "dd2c10bb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Write antonyms for the following words.\n",
      "\n",
      "Input: happy\n",
      "Output: sad\n",
      "\n",
      "Input: tall\n",
      "Output: short\n",
      "\n",
      "Input: funny\n",
      "Output:\n"
     ]
    }
   ],
   "source": [
    "prompt = load_prompt(\"few_shot_prompt.json\")\n",
    "print(prompt.format(adjective=\"funny\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d23faf4",
   "metadata": {},
   "source": [
    "### Examples in the config\n",
    "This shows an example of referencing the examples directly in the config."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "6cd781ef",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\r\n",
      "    \"_type\": \"few_shot\",\r\n",
      "    \"input_variables\": [\"adjective\"],\r\n",
      "    \"prefix\": \"Write antonyms for the following words.\",\r\n",
      "    \"example_prompt\": {\r\n",
      "        \"_type\": \"prompt\",\r\n",
      "        \"input_variables\": [\"input\", \"output\"],\r\n",
      "        \"template\": \"Input: {input}\\nOutput: {output}\"\r\n",
      "    },\r\n",
      "    \"examples\": [\r\n",
      "        {\"input\": \"happy\", \"output\": \"sad\"},\r\n",
      "        {\"input\": \"tall\", \"output\": \"short\"}\r\n",
      "    ],\r\n",
      "    \"suffix\": \"Input: {adjective}\\nOutput:\"\r\n",
      "}   \r\n"
     ]
    }
   ],
   "source": [
    "!cat few_shot_prompt_examples_in.json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "533ab8a7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Write antonyms for the following words.\n",
      "\n",
      "Input: happy\n",
      "Output: sad\n",
      "\n",
      "Input: tall\n",
      "Output: short\n",
      "\n",
      "Input: funny\n",
      "Output:\n"
     ]
    }
   ],
   "source": [
    "prompt = load_prompt(\"few_shot_prompt_examples_in.json\")\n",
    "print(prompt.format(adjective=\"funny\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e86139e",
   "metadata": {},
   "source": [
    "### Example prompt from a file\n",
    "This shows an example of loading the PromptTemplate that is used to format the examples from a separate file. Note that the key changes from `example_prompt` to `example_prompt_path`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "0b6dd7b8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\r\n",
      "    \"_type\": \"prompt\",\r\n",
      "    \"input_variables\": [\"input\", \"output\"],\r\n",
      "    \"template\": \"Input: {input}\\nOutput: {output}\" \r\n",
      "}\r\n"
     ]
    }
   ],
   "source": [
    "!cat example_prompt.json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "76a1065d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\r\n",
      "    \"_type\": \"few_shot\",\r\n",
      "    \"input_variables\": [\"adjective\"],\r\n",
      "    \"prefix\": \"Write antonyms for the following words.\",\r\n",
      "    \"example_prompt_path\": \"example_prompt.json\",\r\n",
      "    \"examples\": \"examples.json\",\r\n",
      "    \"suffix\": \"Input: {adjective}\\nOutput:\"\r\n",
      "}   \r\n"
     ]
    }
   ],
   "source": [
    "!cat few_shot_prompt_example_prompt.json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "744d275d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Write antonyms for the following words.\n",
      "\n",
      "Input: happy\n",
      "Output: sad\n",
      "\n",
      "Input: tall\n",
      "Output: short\n",
      "\n",
      "Input: funny\n",
      "Output:\n"
     ]
    }
   ],
   "source": [
    "prompt = load_prompt(\"few_shot_prompt_example_prompt.json\")\n",
    "print(prompt.format(adjective=\"funny\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c6e3f9fe",
   "metadata": {},
   "source": [
    "## PromptTemplate with OutputParser\n",
    "This shows an example of loading a prompt along with an OutputParser from a file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "500dab26",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\r\n",
      "    \"input_variables\": [\r\n",
      "        \"question\",\r\n",
      "        \"student_answer\"\r\n",
      "    ],\r\n",
      "    \"output_parser\": {\r\n",
      "        \"regex\": \"(.*?)\\\\nScore: (.*)\",\r\n",
      "        \"output_keys\": [\r\n",
      "            \"answer\",\r\n",
      "            \"score\"\r\n",
      "        ],\r\n",
      "        \"default_output_key\": null,\r\n",
      "        \"_type\": \"regex_parser\"\r\n",
      "    },\r\n",
      "    \"partial_variables\": {},\r\n",
      "    \"template\": \"Given the following question and student answer, provide a correct answer and score the student answer.\\nQuestion: {question}\\nStudent Answer: {student_answer}\\nCorrect Answer:\",\r\n",
      "    \"template_format\": \"f-string\",\r\n",
      "    \"validate_template\": true,\r\n",
      "    \"_type\": \"prompt\"\r\n",
      "}"
     ]
    }
   ],
   "source": [
    "! cat prompt_with_output_parser.json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "d267a736",
   "metadata": {},
   "outputs": [],
   "source": [
    "prompt = load_prompt(\"prompt_with_output_parser.json\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "cb770399",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'answer': 'George Washington was born in 1732 and died in 1799.',\n",
       " 'score': '1/2'}"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "prompt.output_parser.parse(\n",
    "    \"George Washington was born in 1732 and died in 1799.\\nScore: 1/2\"\n",
    ")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.3"
  },
  "vscode": {
   "interpreter": {
    "hash": "8eb71adebe840dca1185e9603533462bc47eb1b1a73bf7dab2d0a8a4c932882e"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
